Data Summary

Income/Life Data

We first read in two data sets called “income” and “life” representing income and life expectancy values throughout a multitude of years. “Income” has 193 observations with 220 total variables whilst “Life” has 187 observations and 220 total variables.

income <- read.csv("https://ecoleman451.github.io/ecoleman/w6/income_per_person.csv")

life <- read.csv("https://ecoleman451.github.io/ecoleman/w6/life_expectancy_years.csv")

Reshape Income/Life Data

Next, we reshape both data sets such that there are only three columns (Geo, Year, Income or Life Expectancy):

# Reshape data set such that there are only three columns (Geo, Year, & Income)
new_income <- pivot_longer(income, cols = -geo, names_to = "year", values_to = "income")
head(new_income)
# A tibble: 6 × 3
  geo         year  income
  <chr>       <chr>  <int>
1 Afghanistan X1800    603
2 Afghanistan X1801    603
3 Afghanistan X1802    603
4 Afghanistan X1803    603
5 Afghanistan X1804    603
6 Afghanistan X1805    603
new_life <- pivot_longer(life, cols = -geo, names_to = "year", values_to = "life.expectancy")
head(new_life)
# A tibble: 6 × 3
  geo         year  life.expectancy
  <chr>       <chr>           <dbl>
1 Afghanistan X1800            28.2
2 Afghanistan X1801            28.2
3 Afghanistan X1802            28.2
4 Afghanistan X1803            28.2
5 Afghanistan X1804            28.2
6 Afghanistan X1805            28.2

Create New Data Set

We then merge these two new sets into a data set called “LifeExpIncom” which now contains Geo, Year, Income, & Life Expectancy (40953 observations and 4 variables).

## Create new data set
LifeExpIncom <- merge(new_life, new_income, by = c("geo", "year"))
head(LifeExpIncom)
          geo  year life.expectancy income
1 Afghanistan X1800            28.2    603
2 Afghanistan X1801            28.2    603
3 Afghanistan X1802            28.2    603
4 Afghanistan X1803            28.2    603
5 Afghanistan X1804            28.2    603
6 Afghanistan X1805            28.2    603

Adding in Country/Population Data

We then read in two more sets called “country” (240 observations and 11 variables) and “pop” (195 observations and 220 variables) respectively representing country and population data. We reshape the data set “pop” so that it coincides with “LifeExpIncom” and “Country” which already have the variable Year transformed into one column.

## Read in More Data
country <- read.csv("https://ecoleman451.github.io/ecoleman/w6/countries_total.csv")

pop <- read.csv("https://ecoleman451.github.io/ecoleman/w6/population_total.csv")

new_pop <- pivot_longer(pop, cols = -geo, names_to = "year", values_to = "population")
head(new_pop)
# A tibble: 6 × 3
  geo         year  population
  <chr>       <chr>      <int>
1 Afghanistan X1800    3280000
2 Afghanistan X1801    3280000
3 Afghanistan X1802    3280000
4 Afghanistan X1803    3280000
5 Afghanistan X1804    3280000
6 Afghanistan X1805    3280000
## Merge LifeExpIncom with Country
merged <- merge(LifeExpIncom, country, by.x = "geo", by.y = "name", all.x = TRUE)
head(merged)
          geo  year life.expectancy income alpha.2 alpha.3 country.code
1 Afghanistan X1817            28.0    604      AF     AFG            4
2 Afghanistan X1815            28.1    604      AF     AFG            4
3 Afghanistan X1812            28.1    604      AF     AFG            4
4 Afghanistan X1814            28.1    604      AF     AFG            4
5 Afghanistan X1811            28.1    604      AF     AFG            4
6 Afghanistan X1816            28.1    604      AF     AFG            4
     iso_3166.2 region    sub.region intermediate.region region.code
1 ISO 3166-2:AF   Asia Southern Asia                             142
2 ISO 3166-2:AF   Asia Southern Asia                             142
3 ISO 3166-2:AF   Asia Southern Asia                             142
4 ISO 3166-2:AF   Asia Southern Asia                             142
5 ISO 3166-2:AF   Asia Southern Asia                             142
6 ISO 3166-2:AF   Asia Southern Asia                             142
  sub.region.code intermediate.region.code
1              34                       NA
2              34                       NA
3              34                       NA
4              34                       NA
5              34                       NA
6              34                       NA

Creating Final Data Set

After doing this, we’re able to merge “LifeExpIncom” with “Country” and then this newly merged set with our recently transformed “pop” set, creating a set called “fin_data” (42705 observations and 15 variables).

## Merge Population with Merged Data
fin_data <- merge(new_pop, merged, by = c("geo", "year"), all.x = TRUE)
head(fin_data)
          geo  year population life.expectancy income alpha.2 alpha.3
1 Afghanistan X1800    3280000            28.2    603      AF     AFG
2 Afghanistan X1801    3280000            28.2    603      AF     AFG
3 Afghanistan X1802    3280000            28.2    603      AF     AFG
4 Afghanistan X1803    3280000            28.2    603      AF     AFG
5 Afghanistan X1804    3280000            28.2    603      AF     AFG
6 Afghanistan X1805    3280000            28.2    603      AF     AFG
  country.code    iso_3166.2 region    sub.region intermediate.region
1            4 ISO 3166-2:AF   Asia Southern Asia                    
2            4 ISO 3166-2:AF   Asia Southern Asia                    
3            4 ISO 3166-2:AF   Asia Southern Asia                    
4            4 ISO 3166-2:AF   Asia Southern Asia                    
5            4 ISO 3166-2:AF   Asia Southern Asia                    
6            4 ISO 3166-2:AF   Asia Southern Asia                    
  region.code sub.region.code intermediate.region.code
1         142              34                       NA
2         142              34                       NA
3         142              34                       NA
4         142              34                       NA
5         142              34                       NA
6         142              34                       NA

Subsetting Data for Year 2015

After this, all that is left is to subset the data so that we only focus on data from the year 2015. This gives us our “final_data” (195 observations and 15 variables) set. Now, let’s look at the overall summary statistics for the data set “fin_data” which contains not just data from 2015, but from all years from the data set.

## Get Data for Year 2015
final_data <- subset(fin_data, year =="X2015")
summary(fin_data)
     geo                year             population        life.expectancy
 Length:42705       Length:42705       Min.   :6.420e+02   Min.   : 1.00  
 Class :character   Class :character   1st Qu.:2.830e+05   1st Qu.:31.20  
 Mode  :character   Mode  :character   Median :1.710e+06   Median :35.50  
                                       Mean   :1.298e+07   Mean   :43.13  
                                       3rd Qu.:5.940e+06   3rd Qu.:56.00  
                                       Max.   :1.420e+09   Max.   :84.20  
                                                           NA's   :2268   
     income         alpha.2            alpha.3           country.code  
 Min.   :   247   Length:42705       Length:42705       Min.   :  4.0  
 1st Qu.:   875   Class :character   Class :character   1st Qu.:208.0  
 Median :  1440   Mode  :character   Mode  :character   Median :418.0  
 Mean   :  4591                                         Mean   :424.9  
 3rd Qu.:  3460                                         3rd Qu.:643.0  
 Max.   :178000                                         Max.   :894.0  
 NA's   :1752                                           NA's   :4599   
  iso_3166.2           region           sub.region        intermediate.region
 Length:42705       Length:42705       Length:42705       Length:42705       
 Class :character   Class :character   Class :character   Class :character   
 Mode  :character   Mode  :character   Mode  :character   Mode  :character   
                                                                             
                                                                             
                                                                             
                                                                             
  region.code     sub.region.code intermediate.region.code
 Min.   :  2.00   Min.   : 15.0   Min.   : 5.00           
 1st Qu.:  2.00   1st Qu.: 54.0   1st Qu.:11.00           
 Median : 19.00   Median :154.0   Median :14.00           
 Mean   : 71.74   Mean   :177.9   Mean   :14.89           
 3rd Qu.:142.00   3rd Qu.:202.0   3rd Qu.:17.00           
 Max.   :150.00   Max.   :419.0   Max.   :29.00           
 NA's   :4599     NA's   :4599    NA's   :26061           

Plotly

scatter_plot <- plot_ly(
  data = final_data,
  x = ~income,
  y = ~life.expectancy,
  size = ~population,
  color = ~geo,
  text = ~paste("Country: ", geo, "<br>Population: ", population),
  type = "scatter",
  mode = "markers",
  marker = list(
    opacity = 0.6,  ## Transparency level
    sizemode = "diameter",  ## Set the size mode to diameter
    sizeref = 0.1,  ## Adjust the size reference for better visibility
    line = list(
      color = "black",  ## Boundary color for points
      width = 1  ## Boundary width
    )
  )
)
layout <- list(
  title = "Association Between Life Expectancy and Income (Year 2015)",
  xaxis = list(title = "Income"),
  yaxis = list(title = "Life Expectancy"),
  showlegend = FALSE  ## Hide legend for individual countries
)

## Combine the plot and layout
scatter_plot <- layout(scatter_plot, layout)

## Display the interactive scatter plot
scatter_plot

The above plot shows the relationship between income, life expectancy, and population size across different countries in the year 2015. Each point is a country and the size of the points correlate with the population size of that specific country. The countries are each color coded as well.

The x-axis looks at the income levels for each country. Countries that have higher incomes will be skewed to the right. The y-axis looks at life expectancy. Countries with higher life expectancy will be skewed higher on the y axis. From looking at the plot, we can see that there are some countries that primarily take over the scatter plot as opposed to others depending on population size and income. We can look at whether countries that have higher incomes generally have longer life expectancies or examine the population sizes to see if they correlate with higher or lower income levels.

LS0tDQp0aXRsZTogIlBsb3RseSINCmF1dGhvcjogIkVkd2FyZCBDb2xlbWFuIg0KZGF0ZTogIldlc3QgQ2hlc3RlciBVbml2ZXJzaXR5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICBzbW9vdGhfc2Nyb2xsOiB5ZXMNCiAgICB0aGVtZTogbHVtZW4NCmVkaXRvcl9vcHRpb25zOg0KICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtY29sb3I6bGlnaHRncmF5Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCiAgICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgICBjb2xvcjogIzc4MGMwYzsNCn0NCg0KaDEudGl0bGUgew0KICBmb250LXNpemU6IDI0cHg7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQogIGZvbnQtZmFtaWx5OiBBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmOw0KICBmb250LXZhcmlhbnQtY2Fwczogbm9ybWFsOw0KfQ0KaDQuYXV0aG9yIHsgDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmRhdGUgeyANCiAgZm9udC1zaXplOiAxOHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMSB7IA0KICAgIGZvbnQtc2l6ZTogMjJweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMiB7IA0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IA0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7DQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCg0KLyogVGFiIGZlYXR1cmVzICovDQoubmF2PmxpPmEgew0KICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsNCiAgICBkaXNwbGF5OiBibG9jazsNCiAgICBwYWRkaW5nOiAycHggMTVweDsNCiAgICBjb2xvcjogIzk5MDAwMDsNCn0NCi5uYXYtcGlsbHM+bGkuYWN0aXZlPmEsIC5uYXYtcGlsbHM+bGkuYWN0aXZlPmE6aG92ZXIsIC5uYXYtcGlsbHM+bGkuYWN0aXZlPmE6Zm9jdXMgew0KICAgIGNvbG9yOiAjZmZmZmZmOw0KICAgIGJhY2tncm91bmQtY29sb3I6ICM5OTAwMDA7DQp9DQovKg0KbmF2LXBpbGxzPmxpOm50aC1jaGlsZCgyKSB7DQogICAgYmFja2dyb3VuZDogZ3JlZW47DQogfQ0KICovDQo8L3N0eWxlPg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRSwgY29tbWVudD1OQX0NCm9wdGlvbnMocmVwb3MgPSBsaXN0KENSQU49Imh0dHA6Ly9jcmFuLnJzdHVkaW8uY29tLyIpKQ0KaWYgKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikNCiAgIGxpYnJhcnkodGlkeXZlcnNlKQ0KfQ0KaWYgKCFyZXF1aXJlKCJrbml0ciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJrbml0ciIpDQogICBsaWJyYXJ5KGtuaXRyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb3dwbG90IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImNvd3Bsb3QiKQ0KICAgbGlicmFyeShjb3dwbG90KQ0KfQ0KaWYgKCFyZXF1aXJlKCJsYXRleDJleHAiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygibGF0ZXgyZXhwIikNCiAgIGxpYnJhcnkobGF0ZXgyZXhwKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbG90bHkiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygicGxvdGx5IikNCiAgIGxpYnJhcnkocGxvdGx5KQ0KfQ0KaWYgKCFyZXF1aXJlKCJnYXBtaW5kZXIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiZ2FwbWluZGVyIikNCiAgIGxpYnJhcnkoZ2FwbWluZGVyKQ0KfQ0KaWYgKCFyZXF1aXJlKCJwbmciKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInBuZyIpICAgIA0KICAgIGxpYnJhcnkoInBuZyIpDQp9DQppZiAoIXJlcXVpcmUoIlJDdXJsIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJSQ3VybCIpICAgIA0KICAgIGxpYnJhcnkoIlJDdXJsIikNCn0NCmlmICghcmVxdWlyZSgiY29sb3VycGlja2VyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJjb2xvdXJwaWNrZXIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiY29sb3VycGlja2VyIikNCn0NCmlmICghcmVxdWlyZSgiZ2dhbmltYXRlIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ2FuaW1hdGUiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dhbmltYXRlIikNCn0NCmlmICghcmVxdWlyZSgiZ2lmc2tpIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnaWZza2kiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2lmc2tpIikNCn0NCmlmICghcmVxdWlyZSgibWFnaWNrIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJtYWdpY2siKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgibWFnaWNrIikNCn0NCmlmICghcmVxdWlyZSgiZ3JEZXZpY2VzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnckRldmljZXMiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ3JEZXZpY2VzIikNCn0NCmlmICghcmVxdWlyZSgianBlZyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygianBlZyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJqcGVnIikNCn0NCmlmICghcmVxdWlyZSgiZ2dyaWRnZXMiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdncmlkZ2VzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdncmlkZ2VzIikNCn0NCmlmICghcmVxdWlyZSgicGx5ciIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygicGx5ciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJwbHlyIikNCn0NCmlmICghcmVxdWlyZSgiZ2dpcmFwaCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dpcmFwaCIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ2lyYXBoIikNCn0NCmlmICghcmVxdWlyZSgiaGlnaGNoYXJ0ZXIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImhpZ2hjaGFydGVyIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImhpZ2hjaGFydGVyIikNCn0NCmlmICghcmVxdWlyZSgiZm9yZWNhc3QiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImZvcmVjYXN0IikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImZvcmVjYXN0IikNCn0NCiMjIA0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVFJVRSwgICANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BKQ0KYGBgDQoNCiMgRGF0YSBTdW1tYXJ5DQojIyBJbmNvbWUvTGlmZSBEYXRhDQogIFdlIGZpcnN0IHJlYWQgaW4gdHdvIGRhdGEgc2V0cyBjYWxsZWQgImluY29tZSIgYW5kICJsaWZlIiByZXByZXNlbnRpbmcgaW5jb21lIGFuZCBsaWZlIGV4cGVjdGFuY3kgdmFsdWVzIHRocm91Z2hvdXQgYSBtdWx0aXR1ZGUgb2YgeWVhcnMuICJJbmNvbWUiIGhhcyAxOTMgb2JzZXJ2YXRpb25zIHdpdGggMjIwIHRvdGFsIHZhcmlhYmxlcyB3aGlsc3QgIkxpZmUiIGhhcyAxODcgb2JzZXJ2YXRpb25zIGFuZCAyMjAgdG90YWwgdmFyaWFibGVzLg0KYGBge3IsIGNvbW1lbnQ9TkF9DQppbmNvbWUgPC0gcmVhZC5jc3YoImh0dHBzOi8vZWNvbGVtYW40NTEuZ2l0aHViLmlvL2Vjb2xlbWFuL3c2L2luY29tZV9wZXJfcGVyc29uLmNzdiIpDQoNCmxpZmUgPC0gcmVhZC5jc3YoImh0dHBzOi8vZWNvbGVtYW40NTEuZ2l0aHViLmlvL2Vjb2xlbWFuL3c2L2xpZmVfZXhwZWN0YW5jeV95ZWFycy5jc3YiKQ0KYGBgDQoNCiMjIFJlc2hhcGUgSW5jb21lL0xpZmUgRGF0YQ0KICBOZXh0LCB3ZSByZXNoYXBlIGJvdGggZGF0YSBzZXRzIHN1Y2ggdGhhdCB0aGVyZSBhcmUgb25seSB0aHJlZSBjb2x1bW5zIChHZW8sIFllYXIsIEluY29tZSBvciBMaWZlIEV4cGVjdGFuY3kpOg0KYGBge3IsIGNvbW1lbnQ9TkF9DQojIFJlc2hhcGUgZGF0YSBzZXQgc3VjaCB0aGF0IHRoZXJlIGFyZSBvbmx5IHRocmVlIGNvbHVtbnMgKEdlbywgWWVhciwgJiBJbmNvbWUpDQpuZXdfaW5jb21lIDwtIHBpdm90X2xvbmdlcihpbmNvbWUsIGNvbHMgPSAtZ2VvLCBuYW1lc190byA9ICJ5ZWFyIiwgdmFsdWVzX3RvID0gImluY29tZSIpDQpoZWFkKG5ld19pbmNvbWUpDQoNCm5ld19saWZlIDwtIHBpdm90X2xvbmdlcihsaWZlLCBjb2xzID0gLWdlbywgbmFtZXNfdG8gPSAieWVhciIsIHZhbHVlc190byA9ICJsaWZlLmV4cGVjdGFuY3kiKQ0KaGVhZChuZXdfbGlmZSkNCmBgYA0KDQojIyBDcmVhdGUgTmV3IERhdGEgU2V0DQogIFdlIHRoZW4gbWVyZ2UgdGhlc2UgdHdvIG5ldyBzZXRzIGludG8gYSBkYXRhIHNldCBjYWxsZWQgIkxpZmVFeHBJbmNvbSIgd2hpY2ggbm93IGNvbnRhaW5zIEdlbywgWWVhciwgSW5jb21lLCAmIExpZmUgRXhwZWN0YW5jeSAoNDA5NTMgb2JzZXJ2YXRpb25zIGFuZCA0IHZhcmlhYmxlcykuDQpgYGB7ciwgY29tbWVudD1OQX0NCiMjIENyZWF0ZSBuZXcgZGF0YSBzZXQNCkxpZmVFeHBJbmNvbSA8LSBtZXJnZShuZXdfbGlmZSwgbmV3X2luY29tZSwgYnkgPSBjKCJnZW8iLCAieWVhciIpKQ0KaGVhZChMaWZlRXhwSW5jb20pDQpgYGANCg0KIyMgQWRkaW5nIGluIENvdW50cnkvUG9wdWxhdGlvbiBEYXRhDQogIFdlIHRoZW4gcmVhZCBpbiB0d28gbW9yZSBzZXRzIGNhbGxlZCAiY291bnRyeSIgKDI0MCBvYnNlcnZhdGlvbnMgYW5kIDExIHZhcmlhYmxlcykgYW5kICJwb3AiICgxOTUgb2JzZXJ2YXRpb25zIGFuZCAyMjAgdmFyaWFibGVzKSByZXNwZWN0aXZlbHkgcmVwcmVzZW50aW5nIGNvdW50cnkgYW5kIHBvcHVsYXRpb24gZGF0YS4gV2UgcmVzaGFwZSB0aGUgZGF0YSBzZXQgInBvcCIgc28gdGhhdCBpdCBjb2luY2lkZXMgd2l0aCAiTGlmZUV4cEluY29tIiBhbmQgIkNvdW50cnkiIHdoaWNoIGFscmVhZHkgaGF2ZSB0aGUgdmFyaWFibGUgWWVhciB0cmFuc2Zvcm1lZCBpbnRvIG9uZSBjb2x1bW4uDQpgYGB7ciwgY29tbWVudD1OQX0NCiMjIFJlYWQgaW4gTW9yZSBEYXRhDQpjb3VudHJ5IDwtIHJlYWQuY3N2KCJodHRwczovL2Vjb2xlbWFuNDUxLmdpdGh1Yi5pby9lY29sZW1hbi93Ni9jb3VudHJpZXNfdG90YWwuY3N2IikNCg0KcG9wIDwtIHJlYWQuY3N2KCJodHRwczovL2Vjb2xlbWFuNDUxLmdpdGh1Yi5pby9lY29sZW1hbi93Ni9wb3B1bGF0aW9uX3RvdGFsLmNzdiIpDQoNCm5ld19wb3AgPC0gcGl2b3RfbG9uZ2VyKHBvcCwgY29scyA9IC1nZW8sIG5hbWVzX3RvID0gInllYXIiLCB2YWx1ZXNfdG8gPSAicG9wdWxhdGlvbiIpDQpoZWFkKG5ld19wb3ApDQoNCiMjIE1lcmdlIExpZmVFeHBJbmNvbSB3aXRoIENvdW50cnkNCm1lcmdlZCA8LSBtZXJnZShMaWZlRXhwSW5jb20sIGNvdW50cnksIGJ5LnggPSAiZ2VvIiwgYnkueSA9ICJuYW1lIiwgYWxsLnggPSBUUlVFKQ0KaGVhZChtZXJnZWQpDQpgYGANCg0KIyMgQ3JlYXRpbmcgRmluYWwgRGF0YSBTZXQNCiAgQWZ0ZXIgZG9pbmcgdGhpcywgd2UncmUgYWJsZSB0byBtZXJnZSAiTGlmZUV4cEluY29tIiB3aXRoICJDb3VudHJ5IiBhbmQgdGhlbiB0aGlzIG5ld2x5IG1lcmdlZCBzZXQgd2l0aCBvdXIgcmVjZW50bHkgdHJhbnNmb3JtZWQgInBvcCIgc2V0LCBjcmVhdGluZyBhIHNldCBjYWxsZWQgImZpbl9kYXRhIiAoNDI3MDUgb2JzZXJ2YXRpb25zIGFuZCAxNSB2YXJpYWJsZXMpLg0KYGBge3IsIGNvbW1lbnQ9TkF9DQojIyBNZXJnZSBQb3B1bGF0aW9uIHdpdGggTWVyZ2VkIERhdGENCmZpbl9kYXRhIDwtIG1lcmdlKG5ld19wb3AsIG1lcmdlZCwgYnkgPSBjKCJnZW8iLCAieWVhciIpLCBhbGwueCA9IFRSVUUpDQpoZWFkKGZpbl9kYXRhKQ0KYGBgDQoNCiMjIFN1YnNldHRpbmcgRGF0YSBmb3IgWWVhciAyMDE1DQogIEFmdGVyIHRoaXMsIGFsbCB0aGF0IGlzIGxlZnQgaXMgdG8gc3Vic2V0IHRoZSBkYXRhIHNvIHRoYXQgd2Ugb25seSBmb2N1cyBvbiBkYXRhIGZyb20gdGhlIHllYXIgMjAxNS4gVGhpcyBnaXZlcyB1cyBvdXIgImZpbmFsX2RhdGEiICgxOTUgb2JzZXJ2YXRpb25zIGFuZCAxNSB2YXJpYWJsZXMpIHNldC4gTm93LCBsZXQncyBsb29rIGF0IHRoZSBvdmVyYWxsIHN1bW1hcnkgc3RhdGlzdGljcyBmb3IgdGhlIGRhdGEgc2V0ICJmaW5fZGF0YSIgd2hpY2ggY29udGFpbnMgbm90IGp1c3QgZGF0YSBmcm9tIDIwMTUsIGJ1dCBmcm9tIGFsbCB5ZWFycyBmcm9tIHRoZSBkYXRhIHNldC4NCmBgYHtyLCBjb21tZW50PU5BfQ0KIyMgR2V0IERhdGEgZm9yIFllYXIgMjAxNQ0KZmluYWxfZGF0YSA8LSBzdWJzZXQoZmluX2RhdGEsIHllYXIgPT0iWDIwMTUiKQ0Kc3VtbWFyeShmaW5fZGF0YSkNCmBgYA0KDQojIFBsb3RseQ0KYGBge3IsIGNvbW1lbnQ9TkF9DQpzY2F0dGVyX3Bsb3QgPC0gcGxvdF9seSgNCiAgZGF0YSA9IGZpbmFsX2RhdGEsDQogIHggPSB+aW5jb21lLA0KICB5ID0gfmxpZmUuZXhwZWN0YW5jeSwNCiAgc2l6ZSA9IH5wb3B1bGF0aW9uLA0KICBjb2xvciA9IH5nZW8sDQogIHRleHQgPSB+cGFzdGUoIkNvdW50cnk6ICIsIGdlbywgIjxicj5Qb3B1bGF0aW9uOiAiLCBwb3B1bGF0aW9uKSwNCiAgdHlwZSA9ICJzY2F0dGVyIiwNCiAgbW9kZSA9ICJtYXJrZXJzIiwNCiAgbWFya2VyID0gbGlzdCgNCiAgICBvcGFjaXR5ID0gMC42LCAgIyMgVHJhbnNwYXJlbmN5IGxldmVsDQogICAgc2l6ZW1vZGUgPSAiZGlhbWV0ZXIiLCAgIyMgU2V0IHRoZSBzaXplIG1vZGUgdG8gZGlhbWV0ZXINCiAgICBzaXplcmVmID0gMC4xLCAgIyMgQWRqdXN0IHRoZSBzaXplIHJlZmVyZW5jZSBmb3IgYmV0dGVyIHZpc2liaWxpdHkNCiAgICBsaW5lID0gbGlzdCgNCiAgICAgIGNvbG9yID0gImJsYWNrIiwgICMjIEJvdW5kYXJ5IGNvbG9yIGZvciBwb2ludHMNCiAgICAgIHdpZHRoID0gMSAgIyMgQm91bmRhcnkgd2lkdGgNCiAgICApDQogICkNCikNCmxheW91dCA8LSBsaXN0KA0KICB0aXRsZSA9ICJBc3NvY2lhdGlvbiBCZXR3ZWVuIExpZmUgRXhwZWN0YW5jeSBhbmQgSW5jb21lIChZZWFyIDIwMTUpIiwNCiAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkluY29tZSIpLA0KICB5YXhpcyA9IGxpc3QodGl0bGUgPSAiTGlmZSBFeHBlY3RhbmN5IiksDQogIHNob3dsZWdlbmQgPSBGQUxTRSAgIyMgSGlkZSBsZWdlbmQgZm9yIGluZGl2aWR1YWwgY291bnRyaWVzDQopDQoNCiMjIENvbWJpbmUgdGhlIHBsb3QgYW5kIGxheW91dA0Kc2NhdHRlcl9wbG90IDwtIGxheW91dChzY2F0dGVyX3Bsb3QsIGxheW91dCkNCg0KIyMgRGlzcGxheSB0aGUgaW50ZXJhY3RpdmUgc2NhdHRlciBwbG90DQpzY2F0dGVyX3Bsb3QNCmBgYA0KDQpUaGUgYWJvdmUgcGxvdCBzaG93cyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gaW5jb21lLCBsaWZlIGV4cGVjdGFuY3ksIGFuZCBwb3B1bGF0aW9uIHNpemUgYWNyb3NzIGRpZmZlcmVudCBjb3VudHJpZXMgaW4gdGhlIHllYXIgMjAxNS4gRWFjaCBwb2ludCBpcyBhIGNvdW50cnkgYW5kIHRoZSBzaXplIG9mIHRoZSBwb2ludHMgY29ycmVsYXRlIHdpdGggdGhlIHBvcHVsYXRpb24gc2l6ZSBvZiB0aGF0IHNwZWNpZmljIGNvdW50cnkuIFRoZSBjb3VudHJpZXMgYXJlIGVhY2ggY29sb3IgY29kZWQgYXMgd2VsbC4NCg0KVGhlIHgtYXhpcyBsb29rcyBhdCB0aGUgaW5jb21lIGxldmVscyBmb3IgZWFjaCBjb3VudHJ5LiBDb3VudHJpZXMgdGhhdCBoYXZlIGhpZ2hlciBpbmNvbWVzIHdpbGwgYmUgc2tld2VkIHRvIHRoZSByaWdodC4gVGhlIHktYXhpcyBsb29rcyBhdCBsaWZlIGV4cGVjdGFuY3kuIENvdW50cmllcyB3aXRoIGhpZ2hlciBsaWZlIGV4cGVjdGFuY3kgd2lsbCBiZSBza2V3ZWQgaGlnaGVyIG9uIHRoZSB5IGF4aXMuIEZyb20gbG9va2luZyBhdCB0aGUgcGxvdCwgd2UgY2FuIHNlZSB0aGF0IHRoZXJlIGFyZSBzb21lIGNvdW50cmllcyB0aGF0IHByaW1hcmlseSB0YWtlIG92ZXIgdGhlIHNjYXR0ZXIgcGxvdCBhcyBvcHBvc2VkIHRvIG90aGVycyBkZXBlbmRpbmcgb24gcG9wdWxhdGlvbiBzaXplIGFuZCBpbmNvbWUuIFdlIGNhbiBsb29rIGF0IHdoZXRoZXIgY291bnRyaWVzIHRoYXQgaGF2ZSBoaWdoZXIgaW5jb21lcyBnZW5lcmFsbHkgaGF2ZSBsb25nZXIgbGlmZSBleHBlY3RhbmNpZXMgb3IgZXhhbWluZSB0aGUgcG9wdWxhdGlvbiBzaXplcyB0byBzZWUgaWYgdGhleSBjb3JyZWxhdGUgd2l0aCBoaWdoZXIgb3IgbG93ZXIgaW5jb21lIGxldmVscy4NCg==